﻿// ReSharper disable InconsistentNaming
using System;
using System.Drawing;
using System.Drawing.Imaging;
using CI;
using CI.Mesopotamia.Neural;
using CI.Organism;
using NUnit.Framework;

namespace Mesopotamia.UnitTests.Neural
{
    [TestFixture]
    public class SimpleVisionSystemTests
    {
        private SimpleVisionSystem _svs;
        private CoordinateListenerDelegate _svsCallback;
        private long? _lastCallbackValue;
        private long _callbackCount;
        private Bitmap _bitmap;

        private void VisionCallback(Color inputColour, long outputColour)
        {
            _lastCallbackValue = outputColour;
            _callbackCount++;
        }

        [SetUp]
        public void Setup()
        {
            _svs = new SimpleVisionSystem(SVSFormatType.GreyScale);
            _svsCallback = new CoordinateListenerDelegate(VisionCallback);
            _bitmap = new Bitmap(5, 5, PixelFormat.Format32bppPArgb);
            _lastCallbackValue = null;
            _callbackCount = 0;
        }

        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "bitmap")]
        public void ProcessNewBitmap_NullBitmap_Exception()
        {
            _svs.ProcessNewBitmap(null);
        }

        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "callback")]
        public void RegisterCooridanteListerner_NullCallback_Exception()
        {
            _svs.RegisterCooridanteListerner(0, 0, null);
        }

        [Test]
        public void ProcessNewBitmap_NotifysCallback_Equal()
        {
            var colour = Color.Red;
            SetColourAndProcess(colour);

            Assert.AreEqual(1, _callbackCount, "Callback count is not correct");
            Assert.AreEqual(SimpleVisionSystem.ARGBtoGreyScale(colour), _lastCallbackValue, "Colour not being set correctly");
        }

        private void SetColourAndProcess(Color colour)
        {
            _svs.RegisterCooridanteListerner(0, 0, _svsCallback);
            _bitmap.SetPixel(0, 0, colour);
            _svs.ProcessNewBitmap(_bitmap);
        }

        [Test]
        public void ARGBtoGreyScale_Red_Equal()
        {
            var colourValue = Color.Red;
            Assert.AreEqual((long)(Color.Red.R * SimpleVisionSystem.GreyscaleFromRed),
                            SimpleVisionSystem.ARGBtoGreyScale(colourValue),
                            "Red not converting to greyscale properly");
        }

        [Test]
        public void ARGBtoGreyScale_Blue_Equal()
        {
            var colourValue = Color.Blue;
            Assert.AreEqual((long)(Color.Blue.B * SimpleVisionSystem.GreyscaleFromBlue),
                            SimpleVisionSystem.ARGBtoGreyScale(colourValue),
                            "Blue not converting to greyscale properly");
        }

        [Test]
        public void ARGBtoGreyScale_Green_Equal()
        {
            var colourValue = Color.Green;
            Assert.AreEqual((long)(Color.Green.G * SimpleVisionSystem.GreyscaleFromGreen),
                            SimpleVisionSystem.ARGBtoGreyScale(colourValue),
                            "Green not converting to greyscale properly");
        }
    }
}
